home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / game / board / Exchess.lha / EXChess / main.cpp < prev    next >
C/C++ Source or Header  |  1998-08-22  |  31KB  |  928 lines

  1. /*  Main functions controlling program */
  2.  
  3. #include <iostream.h>
  4. #include <iomanip.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include <stdio.h>
  9. #include <signal.h>
  10. #include <fstream.h>
  11.  
  12. #include "define.h"
  13.  
  14. #if UNIX
  15.  #include <sys/types.h>
  16.  #include <sys/time.h>
  17. #else
  18.  #include <time.h>
  19.  #include <windows.h>
  20.  #undef BLACK
  21.  #undef WHITE
  22.  #include <conio.h>
  23.  #define BLACK 0
  24.  #define WHITE 1
  25. #endif
  26.  
  27. // Custom headers, defining external functions and struct types for
  28. // board, piece and moves.  And defining global variables.
  29.  
  30. #include "chess.h"
  31. #include "const.h"
  32. #include "funct.h"
  33. #include "main.h"
  34. #include "hash.h"
  35.  
  36. // moves to time control, base time, increment, time left;
  37. int omttc = 0, mttc = 0, inc = 0; float base = 30, timeleft = 30;
  38.  
  39. int display_board = 0;
  40. int analysis_mode = 0;
  41. extern int fail;   // flag for fail high/fail low from search
  42. extern move ponder_move;
  43.  
  44. // xboard flag
  45. int xboard, post, ics, ALLEG = 0, hintflag = 0, count = 1;
  46. int ponder_flag = 1, learn_bk, shout_book;
  47. extern int ponder, last_ponder, learn_count, learned, TAB_SIZE, PAWN_SIZE;
  48.  
  49. // executable directory
  50. char exec_path[100];
  51.  
  52. #if UNIX
  53.  fd_set read_fds;
  54.  struct timeval timeout = { 0, 0 };
  55. #endif
  56.  
  57. /*------------------------- Main Function ---------------------------*/
  58. //  Main control function that interacts with the User
  59.  
  60. int main(int argc, char *argv[])
  61. {
  62.   char mstring[10];
  63.   move hint;
  64.   xboard = 0; ponder = 0; ics = 0;
  65.   learn_count = 0; learned = 0; learn_bk = 1; shout_book = 0;
  66.  
  67.    strcpy(exec_path, argv[0]);
  68.    // parsing exec path
  69.    int last_slash = 0;
  70.    for(int j = 0; j < 100; j++) {
  71.      if(exec_path[j] == '\0') break;
  72.      if(exec_path[j] == '\\') last_slash = j;
  73.      if(exec_path[j] == '/') last_slash = j;
  74.    }
  75.  
  76.    exec_path[last_slash+1] = '\0';
  77.   
  78.  
  79.   open_hash(); gen_check_table(); set_score_param();
  80.  
  81.   if(argc > 1) {
  82.     if(!strcmp(argv[1], "xb")) xboard = 1;
  83.     if(!strcmp(argv[1], "hash")) set_hash_size(atoi(argv[2]));
  84.     if(argc > 2)
  85.       if(!strcmp(argv[2], "hash")) set_hash_size(atoi(argv[3]));
  86.   }
  87.  
  88.   if(!xboard) {
  89.     cout << "\nExperimental Chess Program (EXchess) version " << VERS << ","
  90.          << "\nCopyright (C) 1997-98 Daniel C. Homan, Waltham MA, USA"
  91.          << "\nEXchess comes with ABSOLUTELY NO WARRANTY. This is free"
  92.          << "\nsoftware, and you are welcome to redistribute it under"
  93.          << "\ncertain conditions. This program is distributed under the"
  94.          << "\nGNU public license.  See the files license.txt and readme.txt"
  95.          << "\nfor more information.\n\n";
  96.  
  97.     cout << "Hash size = " << TAB_SIZE << " entries, "
  98.          << TAB_SIZE*sizeof(hash_rec) << " bytes\n";
  99.     cout << "Pawn size = " << PAWN_SIZE << " entries, "
  100.          << PAWN_SIZE*sizeof(pawn_rec) << " bytes\n\n";
  101.     cout << "Type 'help' for a list of commands.\n";
  102.   }
  103.  
  104.   setboard(i_pos, 'w', 1);             // set up the board
  105.  
  106.   while (count > 0)
  107.    {
  108.  
  109.     // find a hint move, check book first then look in pv
  110.     if(hintflag) {
  111.       hint.t = 0;
  112.       if(last_ponder) hint = ponder_move;
  113.       else if(book) hint = opening_book(game_pos.hcode, &game_pos);
  114.       if(!hint.t) hint = pc[0][1];
  115.       if(hint.t) {
  116.        print_move(game_pos, hint, mstring);
  117.        cout << "Hint: " << mstring << "\n";
  118.       }
  119.       hintflag = 0;
  120.     }
  121.  
  122.     signal(SIGINT, SIG_IGN);
  123.  
  124.     // pondering if possible
  125.     if(T > 2 && p_side == game_pos.wtm
  126.        && !both && !last_ponder && ponder_flag)
  127.     {
  128.       if(!xboard) cout << "pondering... (press any key to interrupt)\n";
  129.       cout.flush();
  130.       ponder = 1;
  131.       search(game_pos, 10000, T+1);
  132.       ponder = 0;
  133.       last_ponder = 1;
  134.     }
  135.  
  136.     // if analysis_mode, do some analysis
  137.     if(analysis_mode) {
  138.       search(game_pos, 360000, T);
  139.     }
  140.    
  141.     if(!game_pos.wtm)                        // if it is black's turn
  142.     {
  143.      if(both) p_side = 0;
  144.      if(!xboard) cout << "Black-To-Move[" << ceil(T/2) << "]: ";
  145.     }
  146.     else                                         // or if it is white's
  147.     {
  148.      if(both) p_side = 1;
  149.      if(!xboard) cout << "White-To-Move[" << (ceil(T/2) + 1) << "]: ";
  150.     }
  151.  
  152.     cout.flush();
  153.  
  154.     legalmoves(&game_pos, &movelist);     // find legal moves
  155.  
  156.     if(p_side == game_pos.wtm || game_over) {
  157.       cin >> response;      // get the command
  158.       if((last_ponder || analysis_mode) && UNIX) cout << "\n";
  159.       parse_command();      // parse it
  160.     } else {
  161.       if(!xboard) cout << "Thinking ...\n";
  162.       cout.flush();
  163.       make_move();
  164.       last_ponder = 0;
  165.       T++;
  166.     }
  167.  
  168.     cout.flush();
  169.    }
  170.  
  171.   close_hash();
  172.   return 0;
  173. }
  174.  
  175. // Function to takeback moves
  176. // tm is the number of moves to take back.
  177. // 1 or 2 with current setup
  178. void takeback(int tm)
  179. {
  180.  int temp_turn = T;
  181.  setboard(i_pos, 'w', 1);
  182.  T = temp_turn; if(!(T % 2)) p_side = 0;
  183.  if(p_side == 0 && tm == 1) p_side = 1;
  184.  for (int ip = 0; ip <= T-2-tm; ip++)
  185.  {
  186.   exec_move(&game_pos, game_history[ip], 0);
  187.  }
  188.  if(!xboard) drawboard();
  189.  T = T - tm;
  190. }
  191.  
  192.  
  193. // Function to make the next move... If it is the computer's turn, this
  194. // function calls the search algorithm, takes the best move given by that
  195. // search, and makes the move - unless it is a check move: then it flagges
  196. // stale-mate.....
  197. // The function also looks to see if this move places the opponent in check
  198. // or check-mate.
  199.  
  200. void make_move()
  201. {
  202.    time_t mtime = time(NULL); int time_limit, legal;
  203.    char mstring[10];
  204.  
  205.    // If it is not the player's turn, figure out how much time to use,
  206.    // execute the search algorithm to start the search process and return
  207.    // the best move.
  208.  
  209.    if(mttc && mttc < 25)
  210.     { time_limit = int(timeleft/(mttc+1)) + inc; }
  211.    else if (mttc >= 25 || xboard) { time_limit = int(timeleft/25) + inc; }
  212.    else { time_limit = int(timeleft); }
  213.  
  214.    if (p_side != game_pos.wtm)
  215.    {
  216.     best = search(game_pos, time_limit, T);
  217.     timeleft -= time(NULL) - mtime; timeleft += inc;
  218.     if(mttc) { mttc--; if(!mttc) { timeleft += base; mttc = omttc; } }
  219.     if(mttc <= 0 && !xboard) { timeleft = base; mttc = omttc; }
  220.    }
  221.  
  222.    // execute the move....
  223.    temp_pos = game_pos;
  224.    legal = exec_move(&temp_pos, best, 0);
  225.  
  226.    // Is the move legal? if not Error ....
  227.    if (legal)
  228.     {
  229.      // if it is the computer's turn - echo the move
  230.      if(p_side != game_pos.wtm)
  231.       {
  232.        if(game_pos.wtm) { 
  233.          cout << (ceil(T/2) + 1) << ". ";  if(xboard) cout << "... ";
  234.        }
  235.        else { cout << ceil(T/2) << ". ... "; }
  236.        print_move(game_pos, best, mstring);
  237.        cout << mstring;
  238.        cout << "\n";
  239.       }
  240.  
  241.      last_pos = game_pos;        // Save last position
  242.      game_pos = temp_pos;        // actually execute move
  243.  
  244.      // Check if we have, check_mate, stale_mate, or a continuing game...
  245.      switch (check_mate(&game_pos))
  246.      {
  247.       case 0:
  248.         if(game_pos.fifty >= 100)
  249.          { cout << "1/2-1/2 {50 moves}\n";
  250.            if(ics) cout << "tellics draw\n"; }
  251.         else if(check(&game_pos, game_pos.wtm) && !xboard)
  252.          { cout << "Check!\n"; }
  253.         break;
  254.       case 1:
  255.         game_over = 1;
  256.         if(!game_pos.wtm) cout << "1-0 {White Mates}\n";
  257.         else cout << "0-1 {Black Mates}\n";
  258.         break;
  259.       case 2:
  260.         game_over = 1;
  261.         cout << "1/2-1/2 {Stalemate}\n";
  262.      }
  263.  
  264.      game_history[T-1] = best; // record the move in the history list
  265.      p_list[T-1] = game_pos.hcode;
  266.      if(!xboard && display_board) drawboard();  // draw the resulting board
  267.     }
  268.    else { game_over = 1; cout << "Error - please reset"; }
  269.  
  270. }
  271.  
  272.  
  273.  
  274. // This function sets up the board from EPD format
  275.  
  276. void setboard(char inboard[60], char ms, int castle)
  277. {
  278.   int rx = 0, ry = 7, i;  // control variables
  279.  
  280.   // no book learning yet
  281.   learn_count = 0; learned = 0;
  282.  
  283.   // game is not over
  284.   game_over = 0;
  285.   // initializing castling status if necessary
  286.   if (castle) { game_pos.castle = 15; } else { game_pos.castle = 0; }
  287.   // Side to move
  288.   if (ms == 'b')